package com.tg.app.activity.device.settings;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.text.method.HideReturnsTransformationMethod;
import android.text.method.PasswordTransformationMethod;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

import com.tange.base.toolkit.WifiAp;
import com.appbase.custom.constant.CommonConstants;
import com.tange.module.core.wifi.scan.ApScanConfiguration;
import com.tg.app.R;
import com.base.BaseActivity;
import com.tg.app.adapter.DeviceWifiAdapter;
import com.tg.app.helper.DeviceHelper;
import com.tg.appcommon.android.TGLog;
import com.tg.data.bean.DeviceItem;
import com.tg.app.camera.AVIOCTRLDEFs;
import com.tg.app.camera.Camera;
import com.tange.module.camera.hub.CameraHub;
import com.tg.data.media.OnICameraListener;
import com.tange.core.backend.service.http.ClientObserver;
import com.tg.network.socket.http.TGHttp;
import com.tg.app.view.MsgCenterToast;
import com.tg.appcommon.android.CustomInputStream;


import java.util.ArrayList;
import java.util.HashMap;

import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;


public class ChangeDeviceWifiActivity extends BaseActivity implements OnICameraListener, DeviceWifiAdapter.OnAddWifiDeviceClickListener, View.OnClickListener {

    private static final int CONNECT_WIFI = 0x0;
    private static final int WAIT_FOR_DISCONNECTION = 0x01;
    private static final int WAIT_FOR_CREATE_NEW_CAMERA = 0x02;
    private static final int CHANGE_WIFI_TIME_OUT = 0x03;
    private static final int SEARCH_WIFI_TIME_OUT = 0x04;
    private static final String TAG = "ChangeDeviceWifiActivity";
    private DeviceWifiAdapter adapter;
    private Camera camera;
    private final ArrayList<WifiAp> wifiList = new ArrayList<>();
    private EditText wifiNameEditText, wifiPasswordEditText;
    private ImageView ivClear;
    private Button connectButton;
    private String currentSSID;
    private DeviceItem device;
    private LinearLayout mWifiInputLL;
    private WifiAp wifiAp;
    private ListView wifiListView;
    private View mErrorLayout, mWifiTips, mBtnRetry, mSearchLayout;

    @Override
    public boolean shouldSetStatusBarColor() {
        return true;
    }

    private final Handler handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            switch (msg.what) {
                case CONNECT_WIFI:
                    TGLog.d("isConnect=" + camera.isConnected());
                    if (!camera.isConnected()) {
                        camera.connect();
                        camera.registerICameraListener(ChangeDeviceWifiActivity.this);
                        handler.sendEmptyMessageDelayed(CONNECT_WIFI, 1000 * 10);
                    } else {
                        camera.sendIOCtrl(AVIOCTRLDEFs.IOTYPE_USER_IPCAM_GETWIFI_REQ, new byte[4]);
                    }
                    break;

                case WAIT_FOR_DISCONNECTION:
                    TGLog.d("WAIT_FOR_DISCONNECTION");
                    camera.disconnect();
                    camera.unregisterICameraListener(ChangeDeviceWifiActivity.this);
                    handler.sendEmptyMessageDelayed(WAIT_FOR_CREATE_NEW_CAMERA, 1000 * 5);
                    break;

                case WAIT_FOR_CREATE_NEW_CAMERA:
                    TGLog.d("WAIT_FOR_CREATE_NEW_CAMERA device.p2p_id " + device.p2p_id);
                    if (!TextUtils.isEmpty(device.p2p_id) || DeviceHelper.isExistLockBellRelay(device)) {
                        CameraHub.getInstance().removeCamera(camera);
                        camera = CameraHub.getInstance().getCamera(DeviceItem.createBasicDevice(device));
                        handler.sendEmptyMessageDelayed(CONNECT_WIFI, 1000 * 20);
                    }
                    break;

                case CHANGE_WIFI_TIME_OUT:
                    TGLog.d("CHANGE_WIFI_TIME_OUT");
                    hideLoading();
                    MsgCenterToast.show(ChangeDeviceWifiActivity.this, getString(R.string.change_wifi_failed));
                    if (!camera.isConnected()) {
                        camera.connect();
                        camera.registerICameraListener(ChangeDeviceWifiActivity.this);
                    }
                    break;

                case SEARCH_WIFI_TIME_OUT:
                    hideLoading();
                    mBtnRetry.setVisibility(View.VISIBLE);
                    setErrorViewShow(true);
                    break;
            }
            return false;
        }
    });

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_change_device_wifi);
        initView();
        hideActionBar();
        device = getIntent().getParcelableExtra(CommonConstants.EXT_DEVICE_ITEM);
        camera = device == null? null : CameraHub.getInstance().getCamera(device.uuid);
        if (camera != null) {
            camera.registerICameraListener(this);
            if (!camera.isConnected()) {
                mBtnRetry.setVisibility(View.GONE);
                setErrorViewShow(true);
                return;
            }
            camera.registerICameraListener(this);
            sendGetWifiListCmd();
        }

        modifyToolBar();

    }

    private void sendGetWifiListCmd() {
        if (camera != null) {
            camera.sendIOCtrl(AVIOCTRLDEFs.IOTYPE_USER_IPCAM_LISTWIFIAP_REQ, new byte[4]);
            handler.sendEmptyMessageDelayed(SEARCH_WIFI_TIME_OUT, 1000 * 60);
        }
    }

    private void setErrorViewShow(boolean show) {
        if (show) {
            mWifiTips.setVisibility(View.GONE);
            mSearchLayout.setVisibility(View.GONE);
            mErrorLayout.setVisibility(View.VISIBLE);
        } else {
            mErrorLayout.setVisibility(View.GONE);
            mWifiTips.setVisibility(View.VISIBLE);
            mSearchLayout.setVisibility(View.VISIBLE);
        }
    }

    @Override
    protected void initView() {
        TextView title = findViewById(R.id.device_name);
        title.setText(R.string.setting_wifi);
        ImageButton backButton = findViewById(R.id.back_toolbar);
        backButton.setOnClickListener(this);
        wifiListView = findViewById(R.id.search_connect_list);
        adapter = new DeviceWifiAdapter(wifiList, this, this);
        wifiListView.setAdapter(adapter);
        wifiNameEditText = findViewById(R.id.edt_search_connect_wifi_name);
        wifiPasswordEditText = findViewById(R.id.edt_search_connect_wifi_password);
        CheckBox pwdCheckBox = findViewById(R.id.checkbox_search_connect);
        ivClear = findViewById(R.id.iv_search_connect_clear);
        connectButton = findViewById(R.id.btn_search_connect_send_wifi_info);
        connectButton.setOnClickListener(this);
        connectButton.setEnabled(true);
        mWifiInputLL = findViewById(R.id.ll_search_connect_wifi);
        mErrorLayout = findViewById(R.id.change_camera_wifi_search_retry_layout);
        mWifiTips = findViewById(R.id.setting_change_device_wifi_tips_text_view);
        mBtnRetry = findViewById(R.id.btn_change_camera_wifi_search_retry);
        mSearchLayout = findViewById(R.id.change_camera_wifi_search_layout);
        pwdCheckBox.setOnCheckedChangeListener((buttonView, isChecked) -> {
            if (isChecked) {
                wifiPasswordEditText.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
            } else {
                wifiPasswordEditText.setTransformationMethod(PasswordTransformationMethod.getInstance());
            }
            int position = wifiPasswordEditText.getText().toString().trim().length();
            if (position > 0) {
                wifiPasswordEditText.setSelection(position);
            }
        });
        wifiPasswordEditText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void afterTextChanged(Editable editable) {
                if (TextUtils.isEmpty(editable.toString())) {
                    ivClear.setVisibility(View.GONE);
                    if (wifiAp != null && wifiAp.enctype != 1) {
                        connectButton.setEnabled(false);
                    }
                } else {
                    connectButton.setEnabled(true);
                    ivClear.setVisibility(View.VISIBLE);
                }
            }
        });

        wifiNameEditText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void afterTextChanged(Editable editable) {
                connectButton.setEnabled(!TextUtils.isEmpty(editable.toString()));
            }
        });

        ivClear.setOnClickListener(new View.OnClickListener() {
            @Override

            public void onClick(View v) {
                wifiPasswordEditText.setText("");
            }
        });
        mBtnRetry.setOnClickListener(v -> {
            setErrorViewShow(false);
            sendGetWifiListCmd();
        });
    }

    @Override
    public void receiveUpdateConnectStates(int state) {
        runOnUiThread(() -> {
            if (state == Camera.CONNECTION_STATE_WRONG_PASSWORD) {
                getPassword();
            }
        });
    }

    @Override
    public void receiveIOCtrlData(int type, byte[] data) {
        if (type == AVIOCTRLDEFs.IOTYPE_USER_IPCAM_LISTWIFIAP_RESP) {
            wifiList.clear();
            handler.removeMessages(SEARCH_WIFI_TIME_OUT);
            CustomInputStream.InputStream stream = new CustomInputStream.InputStream(data);
            int num = stream.getInt();
            num = Integer.reverseBytes(num);
            if (num > 0) {
                for (int i = 0; i < num; i++) {
                    WifiAp sWifiAp = new WifiAp();
                    sWifiAp.ssid = stream.getString(32);
                    sWifiAp.mode = stream.getByte();
                    //1 无密码
                    sWifiAp.enctype = stream.getByte();
                    //信号强度
                    sWifiAp.signal = stream.getByte();
                    sWifiAp.status = stream.getByte();
                    TGLog.i(TAG, "status=" + sWifiAp.status);
                    if (!TextUtils.isEmpty(sWifiAp.ssid)&&!sWifiAp.ssid.startsWith(ApScanConfiguration.INSTANCE.apNamePrefix())) {
                        wifiList.add(sWifiAp);
                        if (sWifiAp.status == 1) {
                            currentSSID = sWifiAp.ssid;
                            TGLog.i(TAG, "currentWifi=" + currentSSID);
                        }
                    }
                }
            }
            runOnUiThread(() -> {
                hideLoading();
                if (wifiList.size() > 0) {
                    wifiListView.setVisibility(View.VISIBLE);
                    mSearchLayout.setVisibility(View.GONE);
                }
                adapter.notifyDataSetChanged();
            });
        } else if (type == AVIOCTRLDEFs.IOTYPE_USER_IPCAM_GETWIFI_RESP) {
            TGLog.i(TAG, "IOTYPE_USER_IPCAM_GETWIFI_RESP");
            byte[] recBytes = new byte[32];
            int validLength = 0;
            System.arraycopy(data, 0, recBytes, 0, 32);
            for (byte b : recBytes) {
                if (b != 0) {
                    validLength++;
                } else {
                    break;
                }
            }
            byte[] ssidBytes = new byte[validLength];
            System.arraycopy(recBytes, 0, ssidBytes, 0, validLength);
            final String ssid = new String(ssidBytes);
            TGLog.i(TAG, ssid);
            handler.removeMessages(CONNECT_WIFI);
            handler.removeMessages(CHANGE_WIFI_TIME_OUT);
            runOnUiThread(() -> {
                hideLoading();
                if (!TextUtils.equals(ssid, currentSSID)) {
                    for (int i = 0; i < wifiList.size(); i++) {
                        if (TextUtils.equals(ssid, wifiList.get(i).ssid)) {
                            wifiList.get(i).status = 1;
                        } else {
                            wifiList.get(i).status = 0;
                        }
                    }
                    MsgCenterToast.show(ChangeDeviceWifiActivity.this, getString(R.string.setting_success));
                    currentSSID = ssid;
                    adapter.notifyDataSetChanged();
                } else {
                    MsgCenterToast.show(ChangeDeviceWifiActivity.this, getString(R.string.change_wifi_failed));
                }
            });
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (camera != null){
            camera.registerICameraListener(this);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();

        if (camera != null){
            camera.unregisterICameraListener(this);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        if (handler != null){
            handler.removeCallbacksAndMessages(null);
        }
    }

    @Override
    public void onItemClick(int position) {
        wifiAp = wifiList.get(position);
        String wifiName = wifiAp.ssid;
        if (!TextUtils.equals(currentSSID, wifiName)) {
            if (mWifiInputLL.getVisibility() == View.GONE) {
                mWifiInputLL.setVisibility(View.VISIBLE);
            }
            wifiNameEditText.setText(wifiName);
            wifiNameEditText.setSelection(wifiName.length());
            if (wifiAp != null && wifiAp.enctype != 1) {
                connectButton.setEnabled(false);
            }
        } else {
            if (mWifiInputLL.getVisibility() == View.VISIBLE) {
                mWifiInputLL.setVisibility(View.GONE);
            }
        }
    }

    private void getPassword() {
        HashMap<String, String> hashMap = new HashMap<>();
        hashMap.put("device_id", String.valueOf(camera.deviceId));
        TGHttp.getInstance().getDevicePassword(hashMap)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new ClientObserver<DeviceItem>() {
                    @Override
                    protected void onSuccess(DeviceItem content) {
                        if (camera != null && content != null) {
                            camera.disableLanSearch(content.password);
                            camera.reSendPwd();
                        }
                    }
                });
    }

    @Override

    public void onClick(View v) {
        int id = v.getId();
        if (id == R.id.back_toolbar) {
            finish();
        } else if (id == R.id.btn_search_connect_send_wifi_info) {
            if (camera != null && camera.connectionState == Camera.CONNECTION_STATE_CONNECTED) {
                showLoading();
                handler.sendEmptyMessageDelayed(CHANGE_WIFI_TIME_OUT, 1000 * 500);
                camera.sendIOCtrl(AVIOCTRLDEFs.IOTYPE_USEREX_IPCAM_APLINK_SETWIFI_REQ,
                        AVIOCTRLDEFs.EcpQrcodeContent.parseContent(wifiNameEditText.getText().toString().trim(),
                                wifiPasswordEditText.getText().toString().trim(), 1, "change"));
                handler.sendEmptyMessageDelayed(WAIT_FOR_DISCONNECTION, 1000 * 7);
            }
        }
    }
}
